package com.siyoumi.app.sys.service.prize;

import com.siyoumi.app.entity.SysPrize;
import com.siyoumi.app.entity.SysPrizeSet;
import com.siyoumi.app.sys.service.prize.entity.PrizeUseData;
import com.siyoumi.app.service.SysPrizeService;
import com.siyoumi.app.service.SysPrizeSetService;
import com.siyoumi.component.XSpringContext;
import com.siyoumi.component.http.XHttpContext;
import com.siyoumi.exception.XException;
import com.siyoumi.util.XDate;
import com.siyoumi.util.XLog;
import com.siyoumi.util.XReturn;
import com.siyoumi.util.XStr;
import lombok.SneakyThrows;

//奖品使用
abstract public class PrizeUse {
    static String KEY = "PrizeUse::entity";

    @SneakyThrows
    static public PrizeUse getBean(SysPrize entityPrize) {
        String type = entityPrize.getPrize_type();
        if (XStr.isNullOrEmpty(type)) {
            type = "def";
        }

        type = XStr.lineToHump(type);
        type = XStr.toUpperCase1(type);

        String className = XStr.concat("com.siyoumi.app.modules.sys.service.prize.type_use.PrizeUse", type);
        XLog.info(PrizeSend.class, entityPrize.getPrize_type());
        XLog.info(PrizeSend.class, className);
        Class<?> clazz = Class.forName(className);
        PrizeUse app = (PrizeUse) XSpringContext.getBean(clazz);
        XHttpContext.set(KEY, entityPrize);

        return app;
    }

    public SysPrize getEntity() {
        return XHttpContext.get(KEY);
    }


    public SysPrizeSet getEntityPrizeSet() {
        return SysPrizeSetService.getBean().getEntity(getEntity().getPrize_set_id());
    }


    /**
     * 能否核销
     */
    public XReturn useCanCommon(PrizeUseData data) {
        if (getEntity().expire()) {
            return XReturn.getR(20050, "奖品已过期");
        }

        if (getEntity().use()) {
            return XReturn.getR(20051, "已核销");
        }

        if (getEntity().getPrize_del() != 0) {
            return XReturn.getR(20055, "奖品不存在");
        }

        return useCan(data);
    }

    /**
     * 核销
     *
     * @param data
     */
    public XReturn use(PrizeUseData data) {
        XReturn r = useCanCommon(data);
        if (r.err()) {
            return r;
        }

        XLog.info(this.getClass(), "锁奖品");
        SysPrizeService appPrize = SysPrizeService.getBean();
        SysPrize entityPrize = appPrize.getEntityLock(getEntity().getKey());
        if (entityPrize.use()) {
            return XReturn.getR(20051, "已核销");
        }

        SysPrize entityPrizeUpdate = new SysPrize();
        entityPrizeUpdate.setPrize_id(getEntity().getKey());
        entityPrizeUpdate.setPrize_use(1L);
        entityPrizeUpdate.setPrize_use_date(XDate.now());
        entityPrizeUpdate.setPrize_use_uix(getEntity().getKey());

        useBefore(data, entityPrizeUpdate);
        SysPrizeService.getBean().updateById(entityPrizeUpdate);
        r = useAfter(data);
        if (r.err()) {
            throw new XException(r);
        }

        //事务外方法


        return XReturn.getR(0);
    }


    protected abstract XReturn useCan(PrizeUseData data);

    /**
     * 标记核销前（事务内）
     *
     * @param data
     */
    protected XReturn useBefore(PrizeUseData data, SysPrize entityPrizeUpdate) {
        return XReturn.getR(0);
    }

    /**
     * 核销之后调用（事务内）
     *
     * @param data
     */
    abstract protected XReturn useAfter(PrizeUseData data);
}
